/*
* EP-Tracing System : a tool to trace mountain hike.           .kNNx
* Copyright (C) 2009  Raffaello Brondi                         'KNNNk
*                                                             ,XNNNl
* This program is free software:                             ,XNN0'
* you can redistribute it and/or modify                     ,XNNx.
* it under the terms of the                                'XNNl
* GNU General Public License                              .KNN:                     ..
* as published by                                        .0NNo                    .ONNO.
* the Free Software Foundation,                          xNNN.  :dkd,            .KNNNN;
* either version 3 of the License, or                   :NNNK ;XNNNNNo          ,KNNNX:
* (at your option) any later version.                   xNNNNcXNNNNNNk         cNNNNx.
*                                                       ,XNNNNNNNNNNX'       .xNNNK;
*                                                        .lKNNNNNNNK'       :KNNNo
*                                                          ;kNNNNNKxl;'.'l0NNNk.
* This program is distributed in                          .'  .:xXNNNNNNNNNNNO,
* the hope that it will be useful,                       :NNXd'   ,oONNNNNNk,
* but WITHOUT ANY WARRANTY;                              xNNNNN0c.    .;;,.
* without even the implied warranty of                   kNNNNNNNXd'
* MERCHANTABILITY or                                     xNNNNNNNNNNOc.
* FITNESS FOR A PARTICULAR PURPOSE.                      xNNNNNNNNNNNNXd.
* See the GNU General Public License                     ONNNN0.,o0NNNNNNl
* for more details.                                      0NNNNd    kNNNNNX.
*                                                        KNNNNl   oNNNNNXc
*                                                       .XNNNN:  dNNNNNx.
* You should have received a copy                       .XNNNN; lNNNNO'
* of the GNU General Public License                     .XNNNN; 'dxo'
* along with this program.                              .XNNNN;
* If not, see <http://www.gnu.org/licenses/>.            0NNNN:
*                                                        kNNNNc
*                                                        oNNNNd
*                                                        ;NNNN0
* Contact: rbrondi@gmail.com                             .XNNNN;
*                                                         kNNNNd
*                                                         .coo:.
*/


package EP.UI.Trace;

import EP.FileSystemManager;
import EP.GPS.Trip;
import java.util.Vector;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Gauge;
import javax.microedition.lcdui.ImageItem;
import javax.microedition.lcdui.Spacer;
import javax.microedition.lcdui.TextField;
import javax.microedition.location.Criteria;

/**
 *
 * @author Raffaello Brondi
 */
public class TripSetup extends Form {

    /**  Low precision --> 100 meters   */
    private final int PRECISION_LOW = 100;
    /**  Low-medium precision --> 75 meters   */
    private final int PRECISION_LOW_MEDIUM = 75;
    /**  Medium precision --> 50 meters   */
    private final int PRECISION_MEDIUM = 50;
    /**  Medium-high precision --> 25 meters   */
    private final int PRECISION_MEDIUM_HIGH = 25;
    /**
     * High precision --> 5 meters
     */
    private final int PRECISION_HIGH = 5;

    /*private final int POWER_LOW = Criteria.POWER_USAGE_LOW;
    private final int POWER_MEDIUM = Criteria.POWER_USAGE_MEDIUM;
    private final int POWER_HIGH = Criteria.POWER_USAGE_HIGH;

    private final int NO_REQUIREMENTS = 0;*/
    private Vector roots;
    private TextField tripName;
    private ChoiceGroup altitude;
    private ChoiceGroup storages;
    private ChoiceGroup costAllowed;
    private ChoiceGroup powerConsumption;
    private Gauge precision;
    private final Command close;
    private final Command start;
    private FileSystemManager fsm;

    public TripSetup() {
        super("Setup your hike!");

        this.fsm = FileSystemManager.getInstance();
        Thread t =new Thread() {

            public void run() {
                fsm.init();
                return;
            }
        };
        t.start();
        try {
            t.join();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        this.tripName = new TextField("Hike name", "", 32, TextField.ANY);
        this.altitude = new ChoiceGroup("Altitude", Choice.EXCLUSIVE);
        this.precision = new Gauge("Survey precision", true, 5, 1);
        this.precision.setLayout(ImageItem.LAYOUT_DEFAULT);
        this.storages = new ChoiceGroup("Device Storage", Choice.EXCLUSIVE);
        this.costAllowed = new ChoiceGroup("Cost allowed", Choice.EXCLUSIVE);
        this.powerConsumption = new ChoiceGroup("Power consumption", Choice.EXCLUSIVE);

        this.close = new Command("Close", Command.EXIT, 0);
        this.start = new Command("Start", Command.EXIT, 0);
        this.initialize();
    }

    private void initialize() {
        this.roots = fsm.getRoots();

        this.altitude.append("yes", null);
        this.altitude.append("no", null);
        this.altitude.setFitPolicy(Choice.TEXT_WRAP_DEFAULT);
        this.altitude.setSelectedFlags(new boolean[]{false, true});

        for (int i = 0; i < this.roots.size(); i++) {
            this.storages.append((String) (this.roots.elementAt(i)), null);
        }

        this.costAllowed.append("yes", null);
        this.costAllowed.append("no", null);
        this.costAllowed.setSelectedFlags(new boolean[]{false, true});

        this.powerConsumption.append("no requirements", null);
        this.powerConsumption.append("low", null);
        this.powerConsumption.append("medium", null);
        this.powerConsumption.append("high", null);
        this.powerConsumption.setSelectedFlags(new boolean[]{true, false, false, false});

        this.append(this.tripName);
        this.append(new Spacer(16, 5));
        this.append(this.altitude);
        this.append(new Spacer(16, 5));
        this.append(this.precision);
        this.append(new Spacer(16, 5));
        this.append(this.storages);
        this.append(new Spacer(16, 5));
        this.append(this.costAllowed);
        this.append(new Spacer(16, 5));
        this.append(this.powerConsumption);
        this.append(new Spacer(16, 5));

        this.addCommand(this.close);
        this.addCommand(this.start);
    }

    public void setTrip(Trip t) {
        this.altitude.setSelectedIndex(0, t.isAltitudeNeeded());
        this.altitude.setSelectedIndex(1, !t.isAltitudeNeeded());
    }

    public Command getCloseCommand() {
        return this.close;
    }

    public Command getStartCommand() {
        return this.start;
    }

    public boolean getAltitude() {
        return (boolean) (this.altitude.isSelected(0));
    }

    /*public byte getPrecision() {
    return (byte) ();
    }*/
    public String getTripName() {
        return (String) (this.tripName.getString());
    }

    public String getStorage() {
        return (String) (this.roots.elementAt(this.storages.getSelectedIndex()));

    }

    public boolean getCostAllowed() {
        return this.costAllowed.isSelected(0);
    }

    public byte getPowerConsumption() {
        return (byte) (this.powerConsumption.getSelectedIndex());
    }

    /**
     * Returns an int representing the survey precision requested by the user.
     * It uses PRECISION_* predefined values.
     * @return The value of the precision requested by the user.
     */
    public int getPrecision() {
        switch (this.precision.getValue()) {
            case 1:
                return this.PRECISION_LOW;

            case 2:
                return this.PRECISION_LOW_MEDIUM;

            case 3:
                return this.PRECISION_MEDIUM;

            case 4:
                return this.PRECISION_MEDIUM_HIGH;

            case 5:
                return this.PRECISION_HIGH;

            default:
                return this.PRECISION_LOW;
        }
    }

    /**
     * Creates a new Criteria instance tuned with the user trip parameter.
     * @return A new Criteria
     */
    public Criteria getTripCriteria() {
        Criteria c = new Criteria();
        //System.out.println("precision "+this.getPrecision());
        c.setHorizontalAccuracy(this.getPrecision());
        c.setVerticalAccuracy(this.getPrecision());
        c.setPreferredResponseTime(Criteria.NO_REQUIREMENT);
        //System.out.println("Power consumption "+getPowerConsumption());
        c.setPreferredPowerConsumption(this.getPowerConsumption());
        //System.out.println("cost : " + getCostAllowed());
        c.setCostAllowed(this.getCostAllowed());
        c.setSpeedAndCourseRequired(false);
        //System.out.println("altitude " + getAltitude());
        c.setAltitudeRequired(this.getAltitude());
        c.setAddressInfoRequired(false);

        return c;
    }
}
